<?php
class Person
{
    public $name;
    function __construct($name)
    {
        $this->name = $name;
    }
}
//Module 模型
interface Module
{
    function execute();
}
class FtpModule implements Module
{
    function setHost($host)
    {
        //input the class  action
        print "FtpModule:setHost():$host <br>";
    }
    function setUser($user)
    {
        print "FiptMoudle:setUser():$user<br>";
    }
    function execute()
    {
        //to do something~
    }
}
class PersonModule implements Module
{
    function setPerson(Person $person)
    {
        print "PeronsModule::setPeron():{$person->name} <br>";
    }
    function execute()
    {
        //to do somethin
    }
}
class ModuleRunner
{
    //methodname and componet paramets

    private $configData = array(
        "PersonModule" => array("person" => 'bob'),
        "FtpModule" => array('host' => 'example.com')
    );
    private $modules = array();

    //未来写糖语法的 
    //1 动态引入该库
    //
    function init()
    {

        $interface = new ReflectionClass('Module');
        foreach ($this->configData as $moudlename => $params) {
            //这里是第一层 循环每一个类要做的事情
            $module_class = new ReflectionClass($moudlename);
            if (!$module_class->isSubclassOf($interface)) {
                throw new Exception("unkonw moudle type:$moudlename");
            }
            $module = $module_class->newInstance();
            // 在这里新建一个实例
            // new a class instance in there

            foreach ($module_class->getMethods() as $method) {
                //第二层 循环类里面的每个方法
                //$module_class is reflcation class
                $this->handleMethod($module, $method, $params);
            }
            array_push($this->modules, $module);
            //然后把执行过的方法都存起来
        }
    }
    function handleMethod($module, $method, $params)
    {
        $name = $method->getName();
        echo $name . "<br>";
        $args = $method->getParameters();
        //Obejct ReflectionParameter  
        if (count($args) != 1
            || substr($name, 0, 3) != "set") {
            
                // echo "false !!<br>";
                // 如果没有set 字头的就会跳过这个函数  并且只有一个参数（）？只是限制set这个参数吗？
                //那么这个handleMethod 的作用是 过滤函数？
            return false;
        }
        $property = strtolower(substr($name, 3));

        if (!isset($params[$property])) {
            //动态处理
            return false;
        }
        $arg_class = $args[0]->getClass();
        if (empty($arg_class)) {
            // $method->invoke($module, $arg_class->newInstance($params[$property]));
            return false;
        } else {

            $method->invoke($module, $arg_class->newInstance($params[$property]));
        }
    }
}
$test = new ModuleRunner();
$test->init();


?>